package com.zhinan.shiro;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zhinan.common.SysConstant;
import com.zhinan.dao.SysUserMapper;
import com.zhinan.entity.SysUser;
import com.zhinan.service.SysUserService;
import com.zhinan.utils.SessionUtil;
import com.zhinan.utils.UserUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import javax.annotation.Resource;

/**
 * @Description: Shiro自定义Realm
 * @Author: ZhiNan
 * @Date: 2023-04-10 14:37
 * @Version: 1.0
 */
public class UserRealm extends AuthorizingRealm {

    @Resource
    private SysUserMapper sysUserMapper;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    //自定义登录认证方法
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        Object fromSession = SessionUtil.getObjectFromSession(SysConstant.KAPTCHA_SESSION_KEY);
        SysUser sysUser = new SysUser();
        //获取token中的用户工号,密码
        String userNum = token.getPrincipal().toString();
        String credentials = token.getCredentials().toString();
        sysUser.setUserNum(userNum);
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUserNum, sysUser.getUserNum());
        SysUser userDB = sysUserMapper.selectOne(queryWrapper);
        if (ObjectUtil.isEmpty(userDB)) {
            throw new UnknownAccountException();
        }
        //设置Session
        Session session = SecurityUtils.getSubject().getSession();
        session.setAttribute(SysConstant.USER_SESSION, userDB);

        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userDB, userDB.getUserPwd(),
                ByteSource.Util.bytes(userDB.getSalt()),   //加盐后的密码
                getName());  //指定当前Realm的类名
        //将认证的用户 将正确的密码保存到session中
        setAuthorityToSession(userDB);
        return authenticationInfo;
    }

    /**
     * 保存用户信息到Session
     */
    private void setAuthorityToSession(SysUser sysUser) {
        if (ObjectUtil.isEmpty(UserUtil.getUserFromSession())) {
            UserUtil.setUserToSession(sysUser);
        }
    }


}
